package com.inspectortime.webapp.inspector.fee;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.inspectortime.domain.InspectorCompany;
import com.inspectortime.domain.pricing.BaseFeeWithAdjustersCalculator;
import com.inspectortime.domain.pricing.FeeCalculator;
import com.inspectortime.domain.pricing.PricingPlanType;

public class FeeWizardSqFtHelper extends FeeWizardCommonHelper {
	public FeeWizardSqFtHelper(double defaultPrice) {
		this.setType(PricingPlanType.SquareFootage);

		ListEntry entry = null;
		for (int i = 0; i < listPriceRanges.length; i++) {
			entry = new ListEntry();
			entry.field = listPriceRanges[i];
			entry.label = this.getSqFtRangeLabel(listPriceRanges[i]);
			entry.minSqFt = this.getRangeStart(listPriceRanges[i]);
			entry.maxSqFt = this.getRangeEnd(listPriceRanges[i]);
			entry.price = defaultPrice;
			entries.add(entry);
		}
	}

	private static final String[] listPriceRanges = { "0-1000", "1000-1500", "1500-2000", "2000-2500", "2500-3000",
			"3000-3500", "3500-4000", "4000-4500", "4500-5000", "5000-6000",
			"6000-8000", "8000-10000", "10000-20000"  };

	private int getRangeStart(String range) {
		String[] vals = range.split("-");
		int start = Integer.valueOf(vals[0]);
		return start;
	}

	private int getRangeEnd(String range) {
		String[] vals = range.split("-");
		int end = Integer.valueOf(vals[1]);
		end = end - 1;
		return end;
	}

	private List<ListEntry> entries = new ArrayList<ListEntry>();

	private class ListEntry {
		public String field;
		public String label;
		public double price;
		public int minSqFt;
		public int maxSqFt;

		public String toString() {
			return field + ": " + minSqFt + " min, " + maxSqFt + " max";
		}

		public boolean equals(ListEntry o) {
			return o.field.equals(this.field);
		}
	}

	private ListEntry getEntry(String field) {
		for (ListEntry entry : entries) {
			if (entry.field.equals(field)) {
				return entry;
			}
		}
		return null;
	}

	public Map<String, Double> getSqFtRangeFees() {
		Map<String, Double> result = new LinkedHashMap<String, Double>();
		for (ListEntry entry : entries) {
			result.put(entry.field, entry.price);
		}
		return result;
	}

	public String getSqFtRangeLabel(String listPriceRange) {
		DecimalFormat fmt = new DecimalFormat("###,###,##0");
		String label = fmt.format(getRangeStart(listPriceRange)) + " - "
				+ fmt.format(getRangeEnd(listPriceRange));
		return label;
	}

	@Override
	public List<BaseFeeWithAdjustersCalculator> createFeeCalculators() {
		List<BaseFeeWithAdjustersCalculator> calculators = new ArrayList<BaseFeeWithAdjustersCalculator>();
		BaseFeeWithAdjustersCalculator calculator = null;
		for (ListEntry entry : entries) {
			calculator = new BaseFeeWithAdjustersCalculator();
			calculators.add(calculator);
			calculator.setBaseFee(entry.price);
			calculator.setMinSquareFeet(entry.minSqFt);
			calculator.setMaxSquareFeet(entry.maxSqFt);
			calculator.setSource(entry.field);
		}
		return calculators;
	}
	
	public void setPrice(String field, double price) {
		ListEntry entry = getEntry(field);
		entry.price = price;
	}

	public void populateFromCalculators(InspectorCompany company) {
		populateFromCompany(company);
		for (FeeCalculator calculator : company.getFeeCalculators()) {
			if (calculator.getSource() == null) {
				continue;
			}
			ListEntry entry = this.getEntry(calculator.getSource());
			if (entry == null) {
				continue;
			}
			entry.label = this.getSqFtRangeLabel(calculator.getSource());
			entry.minSqFt = (int) calculator.getMinSquareFeet();
			entry.maxSqFt = (int) calculator.getMaxSquareFeet();
			entry.price = calculator.getBaseFee();
		}
	}

	public void sortEntries() {
		Collections.sort(entries, new Comparator() {
			public int compare(Object o1, Object o2) {
				ListEntry e1 = (ListEntry) o1;
				ListEntry e2 = (ListEntry) o2;
				return e1.minSqFt - e2.minSqFt;
			}
		});
	}
}
